home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / ax25subr.c < prev    next >
C/C++ Source or Header  |  1991-03-29  |  3KB  |  148 lines

  1. /* @(#) $Header: ax25subr.c,v 1.7 91/03/28 19:39:12 deyke Exp $ */
  2.  
  3. /* Low level AX.25 routines:
  4.  *  callsign conversion
  5.  *  control block management
  6.  *
  7.  * Copyright 1991 Phil Karn, KA9Q
  8.  */
  9. #include <stdio.h>
  10. #include "global.h"
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "ax25.h"
  14. #include "lapb.h"
  15. #include <ctype.h>
  16.  
  17. /*
  18.  * setcall - convert callsign plus substation ID of the form
  19.  * "KA9Q-0" to AX.25 (shifted) address format
  20.  *   Address extension bit is left clear
  21.  *   Return -1 on error, 0 if OK
  22.  */
  23. int
  24. setcall(out,call)
  25. char *out;
  26. char *call;
  27. {
  28.     int csize;
  29.     unsigned ssid;
  30.     register int i;
  31.     register char *dp;
  32.     char c;
  33.  
  34.     if(out == NULLCHAR || call == NULLCHAR || *call == '\0')
  35.         return -1;
  36.  
  37.     /* Find dash, if any, separating callsign from ssid
  38.      * Then compute length of callsign field and make sure
  39.      * it isn't excessive
  40.      */
  41.     dp = strchr(call,'-');
  42.     if(dp == NULLCHAR)
  43.         csize = strlen(call);
  44.     else
  45.         csize = dp - call;
  46.     if(csize > ALEN)
  47.         return -1;
  48.     /* Now find and convert ssid, if any */
  49.     if(dp != NULLCHAR){
  50.         dp++;   /* skip dash */
  51.         ssid = atoi(dp);
  52.         if(ssid > 15)
  53.             return -1;
  54.     } else
  55.         ssid = 0;
  56.     /* Copy upper-case callsign, left shifted one bit */
  57.     for(i=0;i<csize;i++){
  58.         c = *call++;
  59.         if(islower(c))
  60.             c = toupper(c);
  61.         *out++ = c << 1;
  62.     }
  63.     /* Pad with shifted spaces if necessary */
  64.     for(;i<ALEN;i++)
  65.         *out++ = ' ' << 1;
  66.  
  67.     /* Insert substation ID field and set reserved bits */
  68.     *out = 0x60 | (ssid << 1);
  69.     return 0;
  70. }
  71. int
  72. addreq(a,b)
  73. register char *a,*b;
  74. {
  75.     if (*a++ != *b++) return 0;
  76.     if (*a++ != *b++) return 0;
  77.     if (*a++ != *b++) return 0;
  78.     if (*a++ != *b++) return 0;
  79.     if (*a++ != *b++) return 0;
  80.     if (*a++ != *b++) return 0;
  81.     return (*a & SSID) == (*b & SSID);
  82. }
  83. /* Return iface pointer if 'addr' belongs to one of our interfaces,
  84.  * NULLIF otherwise.
  85.  */
  86. struct iface *
  87. ismyax25addr(addr)
  88. char *addr;
  89. {
  90.     register struct iface *ifp;
  91.  
  92.     for (ifp = Ifaces; ifp; ifp = ifp->next)
  93.         if (ifp->output == ax_output && addreq(ifp->hwaddr, addr))
  94.             break;
  95.     return ifp;
  96. }
  97. void
  98. addrcp(to,from)
  99. register char *to,*from;
  100. {
  101.     *to++ = *from++;
  102.     *to++ = *from++;
  103.     *to++ = *from++;
  104.     *to++ = *from++;
  105.     *to++ = *from++;
  106.     *to++ = *from++;
  107.     *to = (*from & SSID) | 0x60;
  108. }
  109. /* Convert encoded AX.25 address to printable string */
  110. char *
  111. pax25(e,addr)
  112. char *e;
  113. char *addr;
  114. {
  115.     register int i;
  116.     char c;
  117.     char *cp;
  118.  
  119.     cp = e;
  120.     for(i=ALEN;i != 0;i--){
  121.         c = (*addr++ >> 1) & 0x7f;
  122.         if(c != ' ')
  123.             *cp++ = c;
  124.     }
  125.     if((*addr & SSID) != 0)
  126.         sprintf(cp,"-%d",(*addr >> 1) & 0xf);   /* ssid */
  127.     else
  128.         *cp = '\0';
  129.     return e;
  130. }
  131.  
  132. /* Figure out the frame type from the control field
  133.  * This is done by masking out any sequence numbers and the
  134.  * poll/final bit after determining the general class (I/S/U) of the frame
  135.  */
  136. int16
  137. ftype(control)
  138. register int control;
  139. {
  140.     if((control & 1) == 0)  /* An I-frame is an I-frame... */
  141.         return I;
  142.     if(control & 2)         /* U-frames use all except P/F bit for type */
  143.         return (int16)(uchar(control) & ~PF);
  144.     else                    /* S-frames use low order 4 bits for type */
  145.         return (int16)(uchar(control) & 0xf);
  146. }
  147.  
  148.